package config

import (
	"AiSpeaker/constant"
	"AiSpeaker/pkg/logger"
	"encoding/json"
	"fmt"
	"gopkg.in/yaml.v3"
	"os"
)

var (
	GlobalConfig = &Config{}
	execPath     = ""
)

type Config struct {
	ServerConfig *ServerConfig `yaml:"server"`
	AlarmConfig  *AlarmConfig  `yaml:"alarm"`
}

type ServerConfig struct {
	Port int `yaml:"port"`
}

type AlarmConfig struct {
	PushUrl    string `yaml:"pushUrl"`
	DataConfig string `yaml:"dataConfig"`
}

type SpeakerConfig struct {
	Login    string `yaml:"login"`
	AddTask  string `yaml:"addTask"`
	PlayTask string `yaml:"playTask"`
	StopTask string `yaml:"stopTask"`
}

func init() {
	config()
	defaultConfig()
	parseAiConfig()
}

/**
 * 读取配置文件
 */
func config() {
	mainPath, err := os.Getwd()
	if err != nil {
		logger.Error(err)
		return
	}
	execPath = mainPath
	path := fmt.Sprintf(constant.DefaultConfigPathFormat, execPath, constant.DefaultConfigName)
	logger.Infof("配置文件路径 = %s", path)
	data, err := os.ReadFile(path)
	if err != nil {
		logger.Infof("err: %v\n", err)
		return
	}
	if err := yaml.Unmarshal(data, GlobalConfig); err != nil { //使用yaml.Unmarshal将yaml文件中的信息反序列化给Config结构体
		logger.Infof("err: %v\n", err)
		return
	}
}

/**
 * 设置AI算法，音柱 和 音频的关系
 */
func parseAiConfig() {
	dataConfig := GlobalConfig.AlarmConfig.DataConfig
	logger.Infof("算法配置文件路径：%s", dataConfig)
	content, err := os.ReadFile(dataConfig)
	if err != nil {
		logger.Error("读取AI算法和音柱配置数据失败")
		return
	}

	logger.Infof("算法配置内容：\n%v", string(content))

	var aiSpeakerConfigs []AISpeakerConfig
	err = json.Unmarshal(content, &aiSpeakerConfigs)
	if err != nil {
		logger.Error("读取AI算法和音柱配置数据解析失败")
		return
	}

	for _, aiSpeakerConfig := range aiSpeakerConfigs {
		/*
		 * 这里的赋值语句是解决for循环时，共享对象的问题
		 * go 1.22及以上版本，已经修复了该问题，使用1.22及以上版本时可以不需要该赋值语句
		 */
		tmpAiSpeakerConfig := aiSpeakerConfig
		algorithms := tmpAiSpeakerConfig.Algorithm
		speakerId := tmpAiSpeakerConfig.Speaker
		for _, algorithm := range algorithms {
			/*
			 * 这里的赋值语句是解决for循环时，共享对象的问题
			 * go 1.22及以上版本，已经修复了该问题，使用1.22及以上版本时可以不需要该赋值语句
			 */
			tmpAlgorithm := algorithm
			key := fmt.Sprintf(constant.AlgorithmKeyFormat, speakerId, tmpAlgorithm.Type, tmpAlgorithm.DetailKey)
			tmpAlgorithm.Speaker = speakerId
			tmpAlgorithm.Server = tmpAiSpeakerConfig.Server
			tmpAlgorithm.User = tmpAiSpeakerConfig.User
			tmpAlgorithm.Passwd = tmpAiSpeakerConfig.Passwd
			tmpAlgorithm.DeviceId = tmpAiSpeakerConfig.DeviceId
			if tmpAiSpeakerConfig.Volume == 0 {
				tmpAlgorithm.Volume = tmpAiSpeakerConfig.Volume
			} else {
				tmpAlgorithm.Volume = tmpAiSpeakerConfig.Volume
			}

			GlobalMapAiSpeakerConfig[key] = tmpAlgorithm
		}
	}
}

/**
 * 设置默认配置
 */
func defaultConfig() {
	if GlobalConfig.ServerConfig == nil {
		server := &ServerConfig{
			Port: constant.DefaultHttpPort,
		}
		GlobalConfig.ServerConfig = server
	} else {
		if GlobalConfig.ServerConfig.Port == 0 {
			GlobalConfig.ServerConfig.Port = constant.DefaultHttpPort
		}
	}

	dataJson := fmt.Sprintf(constant.DefaultConfigPathFormat, execPath, constant.DefaultDataConfigName)
	if GlobalConfig.AlarmConfig == nil {
		alarm := &AlarmConfig{
			DataConfig: dataJson,
		}
		GlobalConfig.AlarmConfig = alarm
	} else {
		if GlobalConfig.AlarmConfig.DataConfig == "" {
			GlobalConfig.AlarmConfig.DataConfig = dataJson
		}
	}

	configBytes, err := json.Marshal(GlobalConfig)
	if err == nil {
		logger.Infof("配置文件内容如下：\n%v", string(configBytes))
	}

}
